﻿using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using ProduceBasicData.Api.Application.Command.InvoiceAndReceiptManage;
using ProduceBasicData.Domain.InvoiceAndReceiptManage;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;
using ProduceBasicData.Api.Services;

namespace ProduceBasicData.Api.Application.Handler.InvoiceAndReceiptManage
{
    /// <summary>
    /// 开票录入处理类
    /// </summary>
    public class CreateInvoiceHandler : IRequestHandler<CreateInvoiceCommand, ApiResult<int>>
    {
        private readonly IBaseRespository<Invoice> _invoiceRepository;
        private readonly IMapper _mapper;
        private readonly ICodeRuleService codeRuleService;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="invoiceRepository"></param>
        /// <param name="mapper"></param>
        public CreateInvoiceHandler(IBaseRespository<Invoice> invoiceRepository, IMapper mapper,
            ICodeRuleService codeRuleService)
        {
            _invoiceRepository = invoiceRepository;
            _mapper = mapper;
            this.codeRuleService = codeRuleService;
        }
        /// <summary>
        /// 处理开票录入请求
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> Handle(CreateInvoiceCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 1. 转换领域模型
                var invoice = _mapper.Map<Invoice>(request);

                // 2. 生成SystemNo（若为空）- 先生成，再校验
                if (string.IsNullOrEmpty(invoice.SystemNo))
                {
                    var code = await codeRuleService.AutoGenerateCodeAsync("ProduceBasicData.Domain.InvoiceAndReceiptManage.Invoice");
                    invoice.SystemNo = !string.IsNullOrEmpty(code)
                        ? code
                        : $"KP{DateTime.Now:yyyyMMddHHmmssfff}"; // 加毫秒确保唯一
                }

                // 3. 唯一性校验（此时SystemNo已生成，校验有效）
                var invoiceExist = await _invoiceRepository.GetAll()
                    .AnyAsync(x => x.SystemNo == invoice.SystemNo, cancellationToken);
                if (invoiceExist)
                {
                    return new ApiResult<int>
                    {
                        Code = ApiEnum.Failed,
                        Msg = $"开票单号【{invoice.SystemNo}】已存在"
                    };
                }

                // 4. 补充默认值（若前端未传递）
                invoice.InvoiceNo ??= string.Empty;
                invoice.Attachment ??= string.Empty;
                invoice.SalesOrderSubject ??= string.Empty;

                // 5. 保存数据
                await _invoiceRepository.AddAsync(invoice);

                return new ApiResult<int>
                {
                    Code = ApiEnum.Success,
                    Msg = "开票录入成功",
                    Data = invoice.Id
                };
            }
            catch (Exception ex)
            {
                // 记录日志（建议补充）
                // _logger.LogError(ex, "开票录入失败");
                return new ApiResult<int>
                {
                    Code = ApiEnum.Failed,
                    Msg = $"开票录入失败：{ex.Message}"
                };
            }
        }
    }
}
